AWS Fargateにデプロイしたアプリに対して負荷テストを行う
Introduction
先日Fargateで起動したWebアプリに対して負荷テストを実行していたので、
環境の構築方法についての備忘録です。
本稿ではNodeのWebアプリをFargateで起動し、AWSでの分散負荷テストソリューションを つかって構築した環境から負荷テストを実行するまでを記述します。
Environment
以下の環境で試しました。 aws cliは実行可能な前提です。
- OS : MacOS 11.3.1
- Node: 16.2
- Docker : 20.10.12
Build Services
負荷テスト環境を構築
ここにある負荷分散テストソリューションを使えば、
かんたんに環境が構築可能です。
cloudformationテンプレートが公開されているので、これを使ってデプロイするだけで
負荷テストを実行する環境が全部できてしまいます。
さらに、使用方法や具体的な構築方法もデプロイガイドがありますし、
ここにはやってみた記事もあります。
実際に私もこれらを参考に負荷テスト実行環境を作成しました。
(1時間もかからず構築完了)
次に負荷テスト対象となるWebアプリを構築します。
Webアプリをローカルで作成
まずはNodeアプリをローカルで作成します。
npmやyarnでfastifyをインストールしましょう。
% mkdir path/rour/node-apps && cd path/rour/node-apps % npm init #すべてデフォルトでOK % npm install --save fastify
package.jsonのscriptsに起動用コマンドを追記します。
{ "name": "node-apps", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "node index.js" }, "author": "", "license": "ISC", "dependencies": { "fastify": "^3.25.0" } }
アクセスすると固定文字列を返すだけのAPIを定義します。
//index.js const fastify = require('fastify')({ logger: true }) fastify.get('/', async (request, reply) => { return "ok"; }) const start = async () => { try { await fastify.listen(8080,'0.0.0.0') } catch (err) { fastify.log.error(err) process.exit(1) } } start()
npm startで起動。
% npm start > node-apps@1.0.0 start > node index.js {"level":30,"time":1646630037763,"pid":91885,"hostname":"XXXX.local","msg":"Server listening at http://0.0.0.0:8080"}
アクセス確認OKです。
% curl http://localhost:8080 ok
アプリをFargateで動かす
Fargateで動かすために、さきほどのアプリをdocker image化して
ECRへpushします。
まずはDockerfileを作成しましょう。
#Dockerfile FROM --platform=linux/amd64 node:16-alpine WORKDIR /app COPY . . RUN npm install EXPOSE 8080 CMD [ "node", "index.js" ]
私の環境がM1 macなので--platformオプションが必要でした。
(intel macとかwinならFROM node:16-alpineでよいと思われる)
特に変わったとこはやってません。
ファイルコピーとnpmモジュールのインストール、
あとは公開ポートの設定とアプリの起動です。
buildコマンドでdocker imageの作成。
% docker build . -t node-apps
dockerイメージができたので、次はECRにリポジトリを作成してpushします。
まずはリポジトリを作成しましょう。
% aws ecr create-repository --repository-name <リポジトリ名> --region <リージョン>
成功すればリポジトリ情報が返ってきます。
repositoryUriをおぼえておきましょう。
イメージをpushする前にget-login-passwordでログインしておきます。
% aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin <AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com
適当にタグ付け。
% docker tag node-apps:latest <AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com/node-apps:v1
からのpush
% docker push <AWSアカウントID>.dkr.ecr.<リージョン>.amazonaws.com/node-apps:v1
これでECRにイメージがpushされました。
https://<リージョン>.console.aws.amazon.com/ecr/repositories
の(さきほど作成した)リポジトリをクリックすると、pushしたイメージを確認することができます。
その後、ここの
Create ECS Cluster and define Task Definition
にあるとおり、コマンドラインでクラスタの作成からタスクの作成をやってもいいし、
AWSコンソールからポチポチとクラスタ作成とタスク定義(とサービス定義)をやってもよいです。
※セキュリティグループのポート開放(今回なら8080ポート)を忘れずに
タスクが起動したら詳細画面からアクセス用のエンドポイント(publicip)を確認しておきましょう。
テスト実行
さきほど構築した負荷テスト環境の情報が任意のメールアドレス宛にきているので、
その情報(Username、Password、ConsoleのURL)をつかってログインします。
CREATE TESTボタンを押し、下記項目を設定してRUN NOWボタンを押せばテストが開始されます。
項目 | 内容 | 備考 |
---|---|---|
Name | 負荷テストの名前 | |
Descriptio | テストシナリオの説明 | |
Task Count | 起動するDockerコンテナの数 | Max 100 |
Concurrency | タスクあたりの同時接続数 | Max 200 |
Ramp up | 同時接続数に達するまでの時間 | |
Hold For | 同時接続数を維持する時間 | |
Test Type | シンプルテスト or JMater | |
HTTP endpoint under test | ターゲットのURL | シンプルテストの場合 |
HTTP Method | HTTPメソッド | シンプルテストの場合 |
HTTP Headers | HTTPヘッダ | シンプルテストの場合はオプション |
Body Payload | メッセージボディ | シンプルテストの場合はオプション |
テストが終わると結果レポートが表示されます。
また、実行中のメトリクスをCloudwatchで確認することもできます。
Summary
今回はAWS負荷テストソリューションを使った環境構築、
FargateをつかったNodeアプリのデプロイを解説しました。
これで負荷テストも手軽にできますね。